<script setup>
	import { defineEmits, defineProps, ref } from 'vue'
	import Codemirror from 'codemirror-editor-vue3'
	import { useCustomQueryStore } from '@/views/plugin/dashboard/store/customQuery'

	// 引入css文件
	import 'codemirror/lib/codemirror.css'
	// 引入主题 可以从 codemirror/theme/ 下引入多个
	import 'codemirror/theme/idea.css'
	import 'codemirror/theme/dracula.css'
	// 引入语言模式 可以从 codemirror/mode/ 下引入多个
	import 'codemirror/mode/sql/sql.js'
	// 代码提示功能 具体语言可以从 codemirror/addon/hint/ 下引入多个
	import 'codemirror/addon/hint/show-hint.css'
	import 'codemirror/addon/hint/show-hint.js'
	import 'codemirror/addon/hint/sql-hint.js'
	import 'codemirror/addon/hint/anyword-hint.js'
	import 'codemirror/addon/edit/matchbrackets.js'
	import 'codemirror/addon/comment/comment.js'
	import 'codemirror/addon/search/searchcursor.js'
	import { message } from 'ant-design-vue'
	import dataConnectorApi from '@/views/plugin/dashboard/api/dataConnectorApi'
	import SqlToolbar from '@/views/plugin/dashboard/view/data/components/dataset/customQuery/component/SqlToolbar.vue'

	const store = useCustomQueryStore()

	const props = defineProps({
		value: {
			type: String,
			required: true
		},
		selectedTables: {
			type: Array,
			required: true
		},
		tableFields: {
			type: Object,
			required: true
		},
		dataConnectorId: {
			type: String,
			required: true
		}
	})

	const emit = defineEmits(['update:value', 'update:selectedTables', 'onSave'])

	const editor = ref()
	const isDarkTheme = ref(false)

	// SQL编辑器配置
	const cmOptions = {
		mode: 'text/x-sql',
		theme: isDarkTheme.value ? 'dracula' : 'idea',
		line: true,
		lineNumbers: true,
		lineWrapping: true,
		tabSize: 4,
		autoCloseBrackets: true,
		matchBrackets: true,
		hintOptions: {
			completeSingle: false,
			tables: {},
			keywords: [
				'SELECT',
				'FROM',
				'WHERE',
				'AND',
				'OR',
				'INSERT',
				'INTO',
				'VALUES',
				'UPDATE',
				'SET',
				'DELETE',
				'GROUP BY',
				'ORDER BY',
				'HAVING',
				'LIMIT',
				'JOIN',
				'LEFT JOIN',
				'RIGHT JOIN',
				'INNER JOIN',
				'UNION',
				'ALL',
				'AS',
				'DISTINCT',
				'COUNT',
				'SUM',
				'AVG',
				'MAX',
				'MIN',
				'BETWEEN',
				'IN',
				'LIKE',
				'IS',
				'NULL',
				'ASC',
				'DESC',
				'CASE',
				'WHEN',
				'THEN',
				'ELSE',
				'END'
			]
		},
		extraKeys: { 'Ctrl-Space': 'autocomplete' },
		hintDelay: 500,
		autoCloseTags: true,
		autocomplete: true
	}

	// 更新编辑器的表信息
	const updateEditorTables = () => {
		if (editor.value && editor.value.cminstance) {
			const tables = {}
			// 添加表名到提示选项
			tableList.value.forEach((tableName) => {
				tables[tableName] = []
			})
			// 添加表字段信息
			Object.entries(props.tableFields).forEach(([tableName, fields]) => {
				// 在提示中显示字段名称和注释，但实际选择时只使用字段名称
				tables[tableName] = fields.map((f) => ({
					text: f.value, // 实际插入的文本
					displayText: `${f.value} (${f.title})` // 显示的提示文本
				}))
			})

			editor.value.cminstance.options.hintOptions.tables = tables
		}
	}

	// 监听表字段变化
	watch(
		() => props.tableFields,
		() => {
			updateEditorTables()
		},
		{ deep: true }
	)

	// 提取SQL中的表名并更新选中状态
	const updateSelectedTables = (sql) => {
		if (!sql) return

		// 匹配FROM和JOIN后面的表名
		const tableRegex = /(?:FROM|JOIN)\s+([\w.]+)/gi
		const tables = new Set()
		let match

		// 提取所有表名
		while ((match = tableRegex.exec(sql)) !== null) {
			const tableName = match[1].trim()
			tables.add(tableName)
		}

		// 获取新的表名（在sql中出现但未被选中的表名）
		const newTables = Array.from(tables).filter(
			(table) => (!props.selectedTables || !props.selectedTables.includes(table)) && tableList.value.includes(table)
		)

		// 如果有新表名，更新选中状态
		if (newTables.length > 0) {
			const updatedTables = [...props.selectedTables, ...newTables]
			emit('update:selectedTables', updatedTables)
		}
	}

	// 添加粘贴事件监听
	const onReady = (editor) => {
		editor.on('inputRead', (cm, event) => {
			if (!event.text) return
			const text = event.text[0]
			// 当输入字母、点号或空格时触发提示
			if (/[a-zA-Z_.]/.test(text) || text === ' ') {
				cm.showHint({ completeSingle: false })
			}
		})

		// 添加粘贴事件监听，只更新表名，不触发代码提示
		editor.on('paste', (cm, e) => {
			// 使用setTimeout确保在粘贴内容更新到编辑器后执行
			setTimeout(() => {
				const sql = cm.getValue()
				updateSelectedTables(sql)
			}, 0)
		})

		// 初始化时更新表信息
		updateEditorTables()
	}

	defineExpose({
		updateEditorTables,
		editor
	})

	// 数据表列表
	const tableList = ref([])

	// 加载数据表列表
	const loadTables = async () => {
		try {
			tableList.value = await dataConnectorApi.tables({ id: props.dataConnectorId })
			// 加载完数据表后更新编辑器的表信息
			updateEditorTables()
		} catch (error) {
			console.log(error)
			message.error('获取数据表列表失败')
		}
	}

	// 监听数据连接器ID变化
	watch(
		() => props.dataConnectorId,
		(newId) => {
			if (newId) {
				loadTables()
			}
		},
		{ immediate: true }
	)

	// 监听SQL内容变化
	watch(
		() => props.value,
		(newValue) => {
			if (editor.value && editor.value.cminstance) {
				const currentValue = editor.value.cminstance.getValue()
				if (currentValue !== newValue) {
					editor.value.cminstance.setValue(newValue)
					// 提取并更新表名
					updateSelectedTables(newValue)
				}
			}
		}
	)
</script>

<template>
	<!-- SQL编辑器 -->
	<div class="sql-editor-container">
		<SqlToolbar
			v-if="editor"
			:selectedTables="selectedTables"
			:tableList="tableList"
			:editor="editor"
			@update:selectedTables="(val) => emit('update:selectedTables', val)"
			@onSave="
				(val) => {
					emit('onSave', val)
					console.log(val)
				}
			"
		/>

		<!-- SQL编辑器 -->
		<Codemirror
			:value="value"
			:options="cmOptions"
			ref="editor"
			border
			height="200"
			width="100%"
			@ready="onReady"
			@change="(val) => emit('update:value', val)"
		/>
	</div>
</template>

<style scoped>
	.sql-editor-container {
		border: 1px solid #d9d9d9;
		border-radius: 2px;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
	}

	.sql-editor :deep(.cm-editor) {
		height: 500px;
		font-family: 'Consolas', 'Monaco', monospace;
		font-size: 14px;
	}

	.sql-editor :deep(.cm-gutters) {
		background-color: #f7f7f7;
		border-right: 1px solid #ddd;
	}
</style>
<style>
	.CodeMirror-hints {
		z-index: 30000 !important;
	}
</style>
